package com.hsxc.cdz.controller.appController;

import com.hsxc.cdz.base.bean.Bill;
import com.hsxc.cdz.base.bean.MyUser;
import com.hsxc.cdz.base.util.TimeFormatter;
import com.hsxc.cdz.mgmt.GlobalManager;
import com.hsxc.cdz.monitor.FSM.CachePile;
import com.hsxc.cdz.trans.bill.CacheTrade;
import com.hsxc.cdz.trans.bill.CacheTrade.TradeStatus;
import com.hsxc.cdz.trans.bill.TradeManager;
import com.hsxc.cdz.trans.payment.gzhpay.PrePay;
import com.sun.javafx.collections.MappingChange;
import net.sf.json.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Map;
import javax.servlet.http.HttpServletRequest;

/**
 * app充电业务
 *
 * @author 刘力文
 */
@Controller("appCharge")
@RequestMapping("/app")
public class ChargeController {

    /********************************************************************/
    // 返回值常量
    public static final int SUCCESS = 0;
    public static final int FAILURE = 1;
    public static final int ERR_DATA = 2;
    public static final int No_PILE = 3;
    public static final int No_TRADE = 4;
    public static final int No_INSERT = 5;
    public static final int No_PAY = 6;
    public static final int PRE_PAY_FAIL = 7;
    public static final int TRADE_ON = 8;
    public static final int TRADE_READY = 9;
    public static final int PILE_RESERVED = 10;
    public static final int UNKNOWN = 999;
    private static Logger logger = LoggerFactory.getLogger(ChargeController.class);

    @RequestMapping(value = "/charge", method = RequestMethod.POST)
    @ResponseBody
    public Object charge(@RequestBody String data, HttpServletRequest httpServletRequest) {
        logger.info("请求参数为" + data.toString());
        JSONObject json = JSONObject.fromObject(data);
        String pileNO = json.getString("pileNO");
        int chargePort = 0;//默认请求0号接口进行充电
        if (json.has("port"))
            chargePort = json.getInt("port");
        logger.info("请求参数pileNo" + pileNO);
        Subject subject = SecurityUtils.getSubject();
        if (subject == null || subject.getPrincipal() == null) {
            JSONObject result = new JSONObject();
            result.put("added", false);
            result.put("errcode", MyUser.NO_LOGIN);
            result.put("message", "请重新登录登录");
            return result;
        }
        String tel = subject.getPrincipal().toString();
        // final String trueTel = tel;
        if (pileNO == null) {
            return getResult(ERR_DATA, "数据有误,请重新扫码");
        }
        while (tel.length() < 20) {
            tel += "0";
        }
        logger.info("------TEL" + tel + "---------");

        CacheTrade cacheTrade = GlobalManager.tradeManager.getTradeByUserNo(tel);
        //Bill bill = GlobalManager.billManager.getBillByUserNO(tel);
        if (cacheTrade == null) {
//            Reserv reserv1 = GlobalManager.cacheReservManager.queryReservByPileNo(pileNO);
//            if (reserv1 != null) {
//                JSONObject result = new JSONObject();
//                result.put("success", true);
//                result.put("errcode", PILE_RESERVED);
//                result.put("message", "电桩已经被预约,换桩重扫");
//                return result;
//            }
            // 创建新的交易

            Map<String, Object> result = GlobalManager.tradeManager.createTradeWXAPP(pileNO, tel, Bill.WXAPP, chargePort);
            int i = (int) result.get("errcode");
            switch (i) {
                case TradeManager.SUCCESS:
//                    cacheTrade = GlobalManager.tradeManager.getTrade(pileNO, tel);
//                    if (cacheTrade == null) {
//                        logger.error("ERROR 此处；理论上不可能打印");
//                        logger.error("------TEL" + tel + "---------");
//                        logger.error("------pileNo" + pileNO + "---------");
//                        return getResult(No_TRADE, "没有找到该交易");
//                    }
                    String tid = (String) result.get("tid");
                    logger.info("Generating new TRANSACTION [" + tid + "]");
                    return getResult(SUCCESS, tid);
                case TradeManager.FAILURE:
                    return getResult(FAILURE, "操作失败，请重新扫码");
                case TradeManager.NO_INSERT:
                    return getResult(No_INSERT, "请连枪");
                case TradeManager.NO_CACHEPILE:
                    return getResult(No_PILE, "未找到该桩，请重新扫码");
                default:
                    return getResult(FAILURE, "操作失败，请重新扫码");
            }
        } else if (cacheTrade.getTradeStatus() == TradeStatus.TRADE_STATUS_NOPAY) {
            logger.info("有交易没有结算，直接付钱" + cacheTrade.getTid());
            // 下单
            String tid = cacheTrade.getTid();
            JSONObject jsonObject2 = PrePay.order(tid, tel, httpServletRequest.getRemoteAddr(), 4);
            JSONObject result = new JSONObject();
            // 存在交易不存在账单
            if (jsonObject2.getInt("code") == 2) {
                result.put("errcode", SUCCESS);
                result.put("success", true);
                result.put("message", tid);
                return result;
            } else if (jsonObject2.getInt("code") == 0) {
                result.put("success", true);
                result.put("errcode", No_PAY);
                result.put("message", jsonObject2);
                return result;
            } else if (jsonObject2.getInt("code") == 1) {
                result.put("success", true);
                result.put("errcode", PRE_PAY_FAIL);
                result.put("message", "下单出现其他问题，请重新扫码");
                return result;
            } else {
                logger.info("下单返回位置结果");
                getResult(FAILURE, "下单返回位置结果");
            }
        } else if (cacheTrade.getTradeStatus() == TradeStatus.TRADE_STATUS_ON) {
            // 进入扫码充电页面，如果存在进行中的交易，直接让用户停止充电
            JSONObject result = new JSONObject();
            result.put("errcode", TRADE_ON);
            result.put("success", true);
            result.put("message", cacheTrade.getTid());
            return result;
        } else if (cacheTrade.getTradeStatus() == TradeStatus.Trade_STATUS_FAIL || cacheTrade.getTradeStatus() == TradeStatus.TRADE_STATUS_READY) {
            // 进入扫码充电页面，如果存在进行中的交易，且交易为失败状态，直接让重新点击开始充电
            JSONObject result = new JSONObject();
            result.put("errcode", SUCCESS);
            result.put("success", true);
            result.put("message", cacheTrade.getTid());
            return result;
        }
        logger.error("这里我没有找到需要返回什么");
        return null;
    }

    @RequestMapping(value = "/start", method = RequestMethod.GET)
    @ResponseBody
    public Object start(String tid) {
        if (tid == null || "" == tid) {
            logger.error("TRANSCTION number is null or empty!");
            return getResult(ERR_DATA, "交易编号为空");
        }

        CacheTrade trade = GlobalManager.tradeManager.getTrade(tid);
        if (trade == null) {
            logger.error("Can't find TRANSCTION " + tid);
            return getResult(ERR_DATA, "未找到交易");
        }
        CachePile pile = trade.getCachePile();
        if (pile == null) {
            logger.error("Can't find pile for TRANSACTION " + tid);
            return getResult(ERR_DATA, "未找到该桩，请换桩重扫");
        }
        logger.info("TRANSACTION " + tid + "start charging with pile status " + pile.getStatus());
        int i = pile.chargeStart(0, 0, 0, 0, 0.0, TimeFormatter.toTime(), trade.getUserNo());
        if (i == 0) {
            logger.info("TRANSCTION " + tid + "charge success.");
            boolean resultCode = false;
            while (true) {
                CacheTrade tradeConfirm = GlobalManager.tradeManager.getTrade(tid);
                if (tradeConfirm != null && tradeConfirm.getTradeStatus() == TradeStatus.TRADE_STATUS_ON) {
                    resultCode = true;
                    break;
                } else if (tradeConfirm != null && tradeConfirm.getTradeStatus() == TradeStatus.Trade_STATUS_FAIL) {
                    resultCode = false;
                    tradeConfirm.setTradeStatus(TradeStatus.TRADE_STATUS_READY);
                    GlobalManager.tradeManager.newTrade(tradeConfirm);
                    break;
                }
            }
            if (resultCode) {
                logger.info("开始充电返回正确结果码，可以停止充电");
                return getResult(SUCCESS, tid);
            } else {
                // 通过电桩回复响应吗判断没有连桩，收到未连枪需重新发送开始充电请求
                // 客户确定这样做
                logger.info("开始充电返回错误码，表示没有连枪");
                return getResult(No_INSERT, "请连接充电桩.");
            }

        }
        logger.info("TRANSCTION " + tid + "charge fail with code " + i);
        return getResult(FAILURE, "开始充电失败");
    }

    @RequestMapping(value = "/stop", method = RequestMethod.GET)
    @ResponseBody
    public Object stop(String tid, HttpServletRequest request) {
        if (tid == null || tid == "" || tid.equals("")) {
            logger.error("TRANSCTION " + tid + "is null or empty!");
            return getResult(ERR_DATA, "输入数据为空");
        }
        logger.error("Charging stop for TRANSCTION " + tid);
        CacheTrade trade = GlobalManager.tradeManager.getTrade(tid);
        if (trade == null) {
            logger.error("TRANSCTION " + tid + "does not exist!");
            return getResult(ERR_DATA, "交易为空");
        }
        CachePile pile = trade.getCachePile();
        if (pile == null) {
            logger.error("TRANSCTION " + tid + "can't find pile!");
            return getResult(ERR_DATA, "未找到该桩");

        }
        int i = pile.chargeStop(0, 0, trade.getUserNo());
        if (i == 1) {
            logger.info("TRANSCTION " + tid + "stop charging fail!");
            return getResult(FAILURE, "停止失败");

        }
        logger.info("TRANS: tid " + tid + " start to wait for charging-stop response from pile " + pile.getAddress());
        CacheTrade tradeNopay = null;
        while (true) {
            tradeNopay = GlobalManager.tradeManager.getTrade(tid);
            if (tradeNopay != null && tradeNopay.getTradeStatus() == TradeStatus.TRADE_STATUS_NOPAY) {

                break;
            }
//            try {
//                //Thread.sleep(3000);
//
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//                logger.error("sleep线程异常");
//                return getResult(FAILURE, "下单失败");
//            }
        }

        // 下单
        logger.info("---------while循环了-------------");
        JSONObject jsonObject = PrePay.order(tid, tradeNopay.getUserNo(), request.getRemoteAddr(), 4);
        JSONObject result = new JSONObject();
        // 存在交易不存在账单
        if (jsonObject.getInt("code") == 2) {
            result.put("errcode", 1);// 随便写的
            result.put("success", true);
            result.put("message", tid);
            return result;
        } else if (jsonObject.getInt("code") == 0) {
            result.put("success", true);
            result.put("errcode", 0);
            result.put("message", jsonObject);
        } else if (jsonObject.getInt("code") == 1) {
            result.put("success", true);
            result.put("errcode", 7);
            result.put("message", "下单出现其他问题");
        }
        return result;

    }

    public JSONObject getResult(int errcode, String message) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        if (errcode == SUCCESS) {
            result.put("added", true);
        } else {
            result.put("added", false);
        }
        result.put("errcode", errcode);
        result.put("message", message);
        return result;
    }
}
